#include "v4.h"

#include <netinet/in.h>

namespace sfc::net {

struct sys::Socket::Addr : sockaddr_in {
  Addr(const ip::v4::Addr& addr, ip::v4::Port port) {}
};

}  // namespace sfc::net

namespace sfc::net::ip::v4 {

Socket::Socket() noexcept : Base{} {}

Socket::Socket(sys::Type type) : Base{sys::Domain::V4, type} {}

Socket::Socket(sys::Socket&& s) noexcept : Base{mem::move(s)} {}

void Socket::bind(const v4::Addr& addr, Port port) {
  Base::bind({addr, port});
}

void Socket::connect(const v4::Addr& addr, Port port) {
  Base::connect({addr, port});
}

auto Socket::accept() -> Socket {
  return Socket{Base::accept()};
}

TcpStream::TcpStream(Socket&& s) noexcept : Socket{mem::move(s)} {}

auto TcpStream::connect(const v4::Addr& addr, v4::Port port) -> TcpStream {
  auto res = TcpStream{Socket(sys::Type::Stream)};
  res.connect(addr, port);
  return res;
}

TcpListener::TcpListener(Socket&& s) noexcept : Socket{mem::move(s)} {}

auto TcpListener::bind(const v4::Addr& addr, v4::Port port) -> TcpListener {
  auto res = TcpListener{Socket(sys::Type::Stream)};
  res.bind(addr, port);
  res.listen(1024);
  return res;
}

auto TcpListener::accept() -> TcpStream {
  auto res = TcpStream{Socket::accept()};
  return res;
}

}  // namespace sfc::net::ip::v4
